package com.christina.engine.strategy.impl;

import com.christina.engine.strategy.RoutingStrategy;
import com.christina.engine.strategy.model.RoutingContext;
import com.christina.engine.strategy.model.RoutingDecision;
import com.christina.engine.context.model.UserContext;
import com.christina.engine.context.model.ConversationContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Map;

/**
 * 上下文感知的路由策略
 * 根据用户上下文和对话历史进行智能路由
 *
 * @author Christina
 */
@Slf4j
@Component
public class ContextAwareRoutingStrategy implements RoutingStrategy {

    private static final String STRATEGY_NAME = "ContextAwareRouting";
    private static final int PRIORITY = 80; // 中高优先级

    @Override
    public String getStrategyName() {
        return STRATEGY_NAME;
    }

    @Override
    public RoutingDecision makeDecision(RoutingContext context) {
        if (!isApplicable(context)) {
            return RoutingDecision.failure("Context not applicable for context-aware routing", STRATEGY_NAME);
        }

        // 分析用户偏好
        String preferredService = analyzeUserPreferences(context.getUserContext());
        double preferenceConfidence = calculatePreferenceConfidence(context.getUserContext());

        // 分析对话历史
        String conversationService = analyzeConversationHistory(context.getConversationContext());
        double conversationConfidence = calculateConversationConfidence(context.getConversationContext());

        // 分析时间和紧急程度
        String timeBasedService = analyzeTimeAndUrgency(context);
        double timeConfidence = calculateTimeConfidence(context);

        // 综合决策
        RoutingDecision decision = makeCombinedDecision(
                preferredService, preferenceConfidence,
                conversationService, conversationConfidence,
                timeBasedService, timeConfidence,
                context
        );

        return decision;
    }

    /**
     * 分析用户偏好
     *
     * @param userContext 用户上下文
     * @return 推荐的服务
     */
    private String analyzeUserPreferences(UserContext userContext) {
        if (userContext == null || userContext.getPreferences() == null) {
            return null;
        }

        UserContext.UserPreferences prefs = userContext.getPreferences();

        // 检查用户的偏好交通方式，如果设置了说明用户对出行感兴趣
        if (prefs.getPreferredTransportMode() != null && !"不限".equals(prefs.getPreferredTransportMode())) {
            return "TravelDomainService";
        }

        // 检查聊天风格偏好
        if (prefs.getChatStyle() != null) {
            return "ChatDomainService";
        }

        // 检查是否有自定义偏好指向特定服务
        if (prefs.getCustomPreferences() != null) {
            Object preferredService = prefs.getCustomPreferences().get("preferredService");
            if (preferredService instanceof String) {
                return (String) preferredService;
            }
        }

        return null;
    }

    /**
     * 计算偏好置信度
     *
     * @param userContext 用户上下文
     * @return 置信度
     */
    private double calculatePreferenceConfidence(UserContext userContext) {
        if (userContext == null || userContext.getPreferences() == null) {
            return 0.0;
        }

        UserContext.UserPreferences prefs = userContext.getPreferences();
        double confidence = 0.0;

        // 基于设置的偏好数量计算置信度
        int preferenceCount = 0;
        if (prefs.getPreferredTransportMode() != null) preferenceCount++;
        if (prefs.getChatStyle() != null) preferenceCount++;
        if (prefs.getResponseLength() != null) preferenceCount++;
        if (prefs.getCustomPreferences() != null && !prefs.getCustomPreferences().isEmpty()) {
            preferenceCount += prefs.getCustomPreferences().size();
        }

        // 偏好越多，置信度越高
        confidence = Math.min(preferenceCount * 0.1, 0.7);

        return confidence;
    }

    /**
     * 分析对话历史
     *
     * @param conversationContext 对话上下文
     * @return 推荐的服务
     */
    private String analyzeConversationHistory(ConversationContext conversationContext) {
        if (conversationContext == null) {
            return null;
        }

        // 检查当前话题
        String currentTopic = conversationContext.getCurrentTopic();
        if (currentTopic != null) {
            if (currentTopic.toLowerCase().contains("travel") ||
                    currentTopic.toLowerCase().contains("trip") ||
                    currentTopic.toLowerCase().contains("booking")) {
                return "TravelDomainService";
            }

            if (currentTopic.toLowerCase().contains("user") ||
                    currentTopic.toLowerCase().contains("profile") ||
                    currentTopic.toLowerCase().contains("setting")) {
                return "UserDomainService";
            }
        }

        // 分析最近的交互历史
        if (conversationContext.getLastActiveTime() != null) {
            long minutesSinceLastInteraction = ChronoUnit.MINUTES.between(
                    conversationContext.getLastActiveTime(), LocalDateTime.now());

            // 如果最近有交互，继续使用相同的服务类型
            if (minutesSinceLastInteraction < 10) {
                // 使用sessionVariables替代getAttribute方法
                Map<String, Object> sessionVariables = conversationContext.getSessionVariables();
                if (sessionVariables != null) {
                    Object lastServiceObj = sessionVariables.get("lastUsedService");
                    if (lastServiceObj instanceof String) {
                        return (String) lastServiceObj;
                    }
                }
            }
        }

        return "ChatDomainService"; // 默认聊天服务
    }

    /**
     * 计算对话置信度
     *
     * @param conversationContext 对话上下文
     * @return 置信度
     */
    private double calculateConversationConfidence(ConversationContext conversationContext) {
        if (conversationContext == null) {
            return 0.0;
        }

        double confidence = 0.0;

        // 基于话题明确性
        if (conversationContext.getCurrentTopic() != null &&
                !conversationContext.getCurrentTopic().trim().isEmpty()) {
            confidence += 0.3;
        }

        // 基于交互频率
        if (conversationContext.getLastActiveTime() != null) {
            long minutesSinceLastInteraction = ChronoUnit.MINUTES.between(
                    conversationContext.getLastActiveTime(), LocalDateTime.now());

            if (minutesSinceLastInteraction < 5) {
                confidence += 0.4;
            } else if (minutesSinceLastInteraction < 15) {
                confidence += 0.2;
            }
        }

        // 基于上下文完整性
        if (conversationContext.getSessionVariables() != null &&
                !conversationContext.getSessionVariables().isEmpty()) {
            confidence += 0.2;
        }

        return Math.min(confidence, 0.8);
    }

    /**
     * 分析时间和紧急程度
     *
     * @param context 路由上下文
     * @return 推荐的服务
     */
    private String analyzeTimeAndUrgency(RoutingContext context) {
        // 检查紧急标志
        if (Boolean.TRUE.equals(context.getUrgent())) {
            // 紧急请求优先路由到最快的服务
            return "ChatDomainService"; // 假设聊天服务响应最快
        }

        // 检查请求优先级
        Integer priority = context.getPriority();
        if (priority != null && priority > 5) {
            return "ChatDomainService"; // 高优先级请求
        }

        // 基于时间段分析
        LocalDateTime requestTime = context.getRequestTime();
        if (requestTime != null) {
            int hour = requestTime.getHour();

            // 工作时间更可能是出行规划
            if (hour >= 9 && hour <= 18) {
                return "TravelDomainService";
            }

            // 晚上更可能是聊天
            if (hour >= 20 || hour <= 7) {
                return "ChatDomainService";
            }
        }

        return null;
    }

    /**
     * 计算时间置信度
     *
     * @param context 路由上下文
     * @return 置信度
     */
    private double calculateTimeConfidence(RoutingContext context) {
        double confidence = 0.0;

        // 紧急请求有高置信度
        if (Boolean.TRUE.equals(context.getUrgent())) {
            confidence += 0.6;
        }

        // 高优先级请求
        Integer priority = context.getPriority();
        if (priority != null && priority > 5) {
            confidence += 0.3;
        }

        // 时间段分析
        LocalDateTime requestTime = context.getRequestTime();
        if (requestTime != null) {
            confidence += 0.2;
        }

        return Math.min(confidence, 0.7);
    }

    /**
     * 综合决策
     *
     * @param preferredService 偏好服务
     * @param preferenceConfidence 偏好置信度
     * @param conversationService 对话服务
     * @param conversationConfidence 对话置信度
     * @param timeBasedService 时间服务
     * @param timeConfidence 时间置信度
     * @param context 路由上下文
     * @return 路由决策
     */
    private RoutingDecision makeCombinedDecision(
            String preferredService, double preferenceConfidence,
            String conversationService, double conversationConfidence,
            String timeBasedService, double timeConfidence,
            RoutingContext context) {

        // 计算每个服务的综合得分
        Map<String, Double> serviceScores = new java.util.HashMap<>();

        if (preferredService != null) {
            serviceScores.put(preferredService,
                    serviceScores.getOrDefault(preferredService, 0.0) + preferenceConfidence * 0.4);
        }

        if (conversationService != null) {
            serviceScores.put(conversationService,
                    serviceScores.getOrDefault(conversationService, 0.0) + conversationConfidence * 0.4);
        }

        if (timeBasedService != null) {
            serviceScores.put(timeBasedService,
                    serviceScores.getOrDefault(timeBasedService, 0.0) + timeConfidence * 0.2);
        }

        // 选择得分最高的服务
        String bestService = null;
        double bestScore = 0.0;

        for (Map.Entry<String, Double> entry : serviceScores.entrySet()) {
            if (entry.getValue() > bestScore) {
                bestScore = entry.getValue();
                bestService = entry.getKey();
            }
        }

        if (bestService != null && bestScore > 0.3) {
            return RoutingDecision.builder()
                    .targetService(bestService)
                    .confidence(bestScore)
                    .reason(String.format("Context-aware routing based on user preferences (%.2f), " +
                                    "conversation history (%.2f), and timing (%.2f)",
                            preferenceConfidence, conversationConfidence, timeConfidence))
                    .strategyName(STRATEGY_NAME)
                    .valid(true)
                    .needsFallback(bestScore < 0.6)
                    .fallbackService("ChatDomainService")
                    .build();
        }

        return RoutingDecision.failure("Insufficient context information for routing decision", STRATEGY_NAME);
    }

    @Override
    public int getPriority() {
        return PRIORITY;
    }

    @Override
    public boolean isApplicable(RoutingContext context) {
        return context != null &&
                (context.getUserContext() != null ||
                        context.getConversationContext() != null ||
                        context.getUrgent() != null ||
                        context.getPriority() != null);
    }

    @Override
    public double getConfidence(RoutingContext context) {
        if (!isApplicable(context)) {
            return 0.0;
        }

        double confidence = 0.0;

        // 用户上下文可用性
        if (context.getUserContext() != null) {
            confidence += 0.3;
            if (context.getUserContext().getPreferences() != null) {
                confidence += 0.2;
            }
        }

        // 对话上下文可用性
        if (context.getConversationContext() != null) {
            confidence += 0.3;
            if (context.getConversationContext().getCurrentTopic() != null) {
                confidence += 0.1;
            }
        }

        // 紧急性和优先级
        if (context.getUrgent() != null || context.getPriority() != null) {
            confidence += 0.1;
        }

        return Math.min(confidence, 0.8);
    }
}
